﻿

using Avalonia.Controls.Shapes;
using LightCAD.Core.Elements;
using LightCAD.MathLib;
using LightCAD.Three.OpenGL;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using static LightCAD.Core.Elements.LcPolyLine;



namespace LightCAD.Drawing.Actions
{
    public class PolyLineAction : Curve2dAction
    {
        public static string CommandName;
        public static LcCreateMethod[] CreateMethods;
        private List<Vector2> points;
        /// <summary>
        /// 当前绘制图形状态
        /// </summary>
        private PlineSegmentType polyLineType { get; set; }
        /// <summary>
        /// 多段线第一个点
        /// </summary>
        private Vector2 startPoint { get; set; }
        /// <summary>
        /// 每节线的开始点
        /// </summary>
        private Vector2 firstPoint { get; set; }
        /// <summary>
        /// 每节线的第二个点
        /// </summary>
        private Vector2 secondPoint { get; set; }
        private double Angle { get; set; }
        /// <summary>
        /// 零时集合
        /// </summary>
        private List<Curve2d> Segments { get; set; }
        static PolyLineAction()
        {

            CreateMethods = new LcCreateMethod[3];
            CreateMethods[0] = new LcCreateMethod()
            {
                Name = "CreatePolyLine",
                Description = "创建多段线",
                Steps = new LcCreateStep[]
                {
                    new LcCreateStep { Name=  "Step0", Options= "PLINE指定起点:" },
                    new LcCreateStep { Name=  "Step1", Options= "PLINE下一个点或[圆弧(A)/半宽(H)/长度(L)/放弃(U)/宽度(W)]:" },
                    new LcCreateStep { Name=  "Step2", Options= "PLINE下一个点或[圆弧(A)/半宽(H)/长度(L)/放弃(U)/宽度(W)/闭合(C)]:" },
                    new LcCreateStep { Name=  "Step3", Options= "PLINE[角度(A)/圆心(CE)/闭合(CL)/方向(D)/半宽(H)/直线(L)/半径(R)/第二个点(S)/放弃(U)/宽度(W)]:" },
                }
            };

        }

        internal static void Initilize()
        {
            ElementActions.PolyLine = new PolyLineAction();
            LcDocument.ElementActions.Add(BuiltinElementType.PloyLine, ElementActions.PolyLine);
        }
        private InElementsInputer InElementsInputer { get; set; }
        private ElementSetInputer ElementInputers { get; set; }
        private ElementInputer ElementInputer { get; set; }
        private CmdTextInputer CmdTextInputer { get; set; }
        private PointInputer PointInputer { get; set; }
        private PolyLineAction() { }
        public PolyLineAction(IDocumentEditor docEditor) : base(docEditor)
        {
            this.commandCtrl.WriteInfo("命令：PLINE");
        }

        public async void ExecCreate(string[] args = null)
        {
            //DocumentManager.CurrentRecorder.BeginAction("PolyLine");
            this.StartCreating();
            this.Segments = new List<Curve2d>();
            var curMethod = CreateMethods[0];
            this.ElementInputers = new ElementSetInputer(this.docEditor);
            this.CmdTextInputer = new CmdTextInputer(this.docEditor);
            this.PointInputer = new PointInputer(this.docEditor);
            string name = "";
            string description = "";
            Step0:
            polyLineType = PlineSegmentType.Line;
            var step0 = curMethod.Steps[0];
            var result0 = await PointInputer.Execute(step0.Options);
            if (PointInputer.isCancelled) { this.Cancel(); return; }
            // zcb: 增加Res0为空的判定
            if (result0 == null)
            {
                this.Cancel();
                goto End;
            }
            if (result0.ValueX == null)
            {
                if (result0.Option != null)
                {
                    goto Step0;
                    //TODO:AutoCAD画线输入一个数字，是怎么确定点的？
                }
                else
                    goto Step1;
            }
            else
            {

                this.startPoint = (Vector2)result0.ValueX;
                this.firstPoint = (Vector2)result0.ValueX;
                goto Step1;
            }
            Step1:
            var step1 = curMethod.Steps[1];
            var result1 = await PointInputer.Execute(step1.Options);
            if (PointInputer.isCancelled)
            {
                this.Cancel();
                return;
            }
            if (result1.ValueX != null && result1.Option != null)
            {
                Vector2 pointB = (Vector2)result1.ValueX;
                Vector2 direction = (pointB - firstPoint).Normalize();
                //   result1 = firstPoint + direction * double.Parse(result1.Option) / this.vportRt.Viewport.Scale;
                result1.ValueX = firstPoint + direction * double.Parse(result1.Option);
            }
           if (result1.ValueX == null)
            {
                if (result1.Option == "A")
                {
                    goto Step3;
                }
            }
            else
            {
                this.secondPoint = (Vector2)result1.ValueX;
                Line2d pl = new Line2d();
                pl.Start = (Vector2)this.firstPoint;
                pl.End = (Vector2)this.secondPoint;

                Segments.Add(pl);//第一段直线
                this.firstPoint = (Vector2)result1.ValueX;
                goto Step2;
            }

            Step2:
            polyLineType = PlineSegmentType.Line;
            var step2 = curMethod.Steps[2];
            var result2 = await PointInputer.Execute(step2.Options);
            if (PointInputer.isCancelled)
            {
                this.Cancel();
                goto End;
            }
            if (result2.ValueX != null && result2.Option != null)
            {
                Vector2 pointB = (Vector2)result2.ValueX;
                Vector2 direction = (pointB - firstPoint).Normalize();
                //   result1 = firstPoint + direction * double.Parse(result1.Option) / this.vportRt.Viewport.Scale;
                result2.ValueX = firstPoint + direction * double.Parse(result2.Option);
            }
            if (result2.ValueX == null)
            {
                if (result2.Option.ToUpper() == "A")
                {
                    goto Step3;
                }
                else if (result2.Option.ToUpper() == "C")
                {
                    CreatePolyLine(true, Segments);//创建segments
                    goto End;
                }
                else
                {
                    if (Segments.Count > 0)
                        CreatePolyLine(false, Segments);
                    goto End;
                }

            }
            else
            {

                this.secondPoint = (Vector2)result2.ValueX;
                Line2d pl = new Line2d();
                pl.Start = (Vector2)this.firstPoint;
                pl.End = (Vector2)this.secondPoint;

                Segments.Add(pl);//第二段直线
                this.firstPoint = (Vector2)result2.ValueX;
                goto Step2;
            }
            Step3:
            polyLineType = PlineSegmentType.Arc;//多段线类型是圆弧
            var step3 = curMethod.Steps[3];
            var result3 = await PointInputer.Execute(step3.Options);
            if (PointInputer.isCancelled)
            {
                this.Cancel();
                if (Segments.Count > 0)
                    CreatePolyLine(false, Segments);
                goto End;
            }
            if (result3.ValueX == null)
            {
                if (result3.Option.ToUpper() == "L")
                {
                    goto Step2;
                }
                else if (result3.Option.ToUpper() == "C")
                {
                    CreatePolyLine(true, Segments);//创建元素
                    goto End;
                }
                else
                {
                    if (Segments.Count > 0)
                        CreatePolyLine(false, Segments);
                    goto End;
                }
            }
            else
            {
                this.secondPoint = (Vector2)result3.ValueX;
                PlineSegment pl = new PlineSegment();
                pl.Start = (Vector2)this.firstPoint;
                pl.End = (Vector2)this.secondPoint;
                pl.Type = PlineSegmentType.Arc;

                Vector2 lastend;
                if (Segments.Count == 0)
                {
                    lastend = new(this.firstPoint.X - 5, this.firstPoint.Y);
                }
                else
                if (Segments.LastOrDefault().Type == Curve2dType.Arc2d)
                {
                    var arc2d = Segments.LastOrDefault() as Arc2d;
                    lastend = GetVerticalpoint(arc2d.Endp, arc2d.Center, arc2d.Startp, Angle);

                }
                else
                    lastend = (Segments.LastOrDefault() as Line2d).Start;

                var cir = GetCircleBylinePoint(lastend, pl.Start, pl.End);
                if (cir == null)
                {
                    Line2d lin2 = new Line2d();
                    lin2.Start = (Vector2)this.firstPoint;
                    lin2.End = (Vector2)this.secondPoint;
                    Segments.Add(lin2);
                    goto Step3;
                }
                else
                {


                    Angle = cir.Item3;
                    Arc2d arc2D = new Arc2d();
                    if (GeoUtils.IsTopInLine(lastend, this.firstPoint, this.secondPoint) > 0)
                    {
                        arc2D = Arc2d.CreatePCE(this.secondPoint, cir.Item1, this.firstPoint);

                    }
                    else
                        arc2D = Arc2d.CreatePCE(this.firstPoint, cir.Item1, (Vector2)this.secondPoint);
                    //Arc2d arc2D = new Arc2d();
                    //arc2D.Center = cir.Item1;
                    //arc2D.Startp = (Vector2)this.firstPoint;
                    //arc2D.Endp = (Vector2)this.secondPoint;
                    //arc2D.Radius = Vector2.Distance(arc2D.Center, arc2D.Startp);
                    //double Degrees;
                    //arc2D.StartAngle = GetDegreesByTwoLine(new(arc2D.Center.X, arc2D.Center.Y), new(arc2D.Center.X + arc2D.Radius, arc2D.Center.Y), new(arc2D.Center.X, arc2D.Center.Y), new(arc2D.Startp.X, arc2D.Startp.Y));
                    //arc2D.EndAngle = GetDegreesByTwoLine(new(arc2D.Center.X, arc2D.Center.Y), new(arc2D.Center.X + arc2D.Radius, arc2D.Center.Y), new(arc2D.Center.X, arc2D.Center.Y), new(arc2D.Endp.X, arc2D.Endp.Y));
                    //if (IsTopInLine(arc2D.Center, arc2D.Startp, new(arc2D.Center.X + arc2D.Radius, arc2D.Center.Y)) < 0)
                    //{
                    //    arc2D.StartAngle = 360 - arc2D.StartAngle;
                    //}
                    //if (IsTopInLine(arc2D.Center, arc2D.Endp, new(arc2D.Center.X + arc2D.Radius, arc2D.Center.Y)) < 0)
                    //{

                    //    arc2D.EndAngle = 360 - arc2D.EndAngle;
                    //}
                    //double xAngle = arc2D.EndAngle - arc2D.StartAngle;
                    //if (xAngle < 0)
                    //{
                    //    xAngle += 360;
                    //}
                    //if (xAngle - 0.1 < cir.Item3 && cir.Item3 < xAngle + 0.1)
                    //{
                    //    arc2D.StartAngle = arc2D.StartAngle / 180 * Math.PI;
                    //    arc2D.EndAngle = arc2D.EndAngle / 180 * Math.PI;

                    //}
                    //else
                    //{
                    //    Degrees = arc2D.StartAngle;
                    //    arc2D.StartAngle = arc2D.EndAngle / 180 * Math.PI;
                    //    arc2D.EndAngle = Degrees / 180 * Math.PI;
                    //    arc2D.Startp = (Vector2)this.secondPoint;
                    //    arc2D.Endp = (Vector2)this.firstPoint;
                    //}
                    arc2D.Midp = arc2D.Getmidpoint();
                    Segments.Add(arc2D);
                    this.firstPoint = (Vector2)result3.ValueX;
                    goto Step3;
                }
            }
            End:
            this.EndCreating();
        }
        private bool CreatePolyLine(bool isClosed, List<Curve2d> Segments)
        {
            var doc = this.docRt.Document;
            DocumentManager.CurrentRecorder.BeginAction("PolyLine");
            var PolyLine = doc.CreateObject<LcPolyLine>();
            PolyLine.IsClosed = isClosed;
            PolyLine.Curve2ds = Segments;
            doc.ModelSpace.InsertElement(PolyLine);
            this.docRt.Action.ClearSelects();
            DocumentManager.CurrentRecorder.EndAction();
            return true;
        }
        public override void Cancel()
        {
            base.Cancel();
            this.vportRt.SetCreateDrawer(null);
            //TODO:
            this.EndCreating();
        }
        private void test()
        {
            // this.vportRt.Renderer.DrawRect()
        }
        public override void Draw(SKCanvas canvas, LcElement element, Vector2 offset)
        {
            Matrix3 matrix = Matrix3.GetTranslate(offset);
            var grp = element as LcPolyLine;
            foreach (var ele in grp.Curve2ds)
            {
                var pen = this.GetDrawPen(element);
                if (ele.Type == Curve2dType.Line2d)
                {
                    var mstart = matrix.MultiplyPoint((ele as Line2d).Start);
                    var mend = matrix.MultiplyPoint((ele as Line2d).End);
                    var start = this.vportRt.ConvertWcsToScr(mstart).ToSKPoint();
                    var end = this.vportRt.ConvertWcsToScr(mend).ToSKPoint();
                    if (pen == Constants.defaultPen)
                    {
                        using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                        {

                            canvas.DrawLine(start, end, elePen);
                        }
                    }
                    else
                    {
                        canvas.DrawLine(start, end, pen);
                    }
                }
                else if (ele.Type == Curve2dType.Arc2d)
                {
                    using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                    {
                        this.vportRt.DrawArc(ele as Arc2d, matrix, canvas, elePen);
                    }
                }
            }
            if (grp.IsClosed)
            {
                Vector2 s = new Vector2();
                Vector2 e = new Vector2();
                if (grp.Curve2ds.FirstOrDefault() is Line2d)
                {
                    s = (grp.Curve2ds.FirstOrDefault() as Line2d).Start;
                }
                else
                {
                    s = (grp.Curve2ds.FirstOrDefault() as Arc2d).Startp;
                }
                if (grp.Curve2ds.LastOrDefault() is Line2d)
                {
                    e = (grp.Curve2ds.LastOrDefault() as Line2d).End;
                }
                else
                {
                    e = (grp.Curve2ds.LastOrDefault() as Arc2d).Endp;
                }

                var cstart = this.vportRt.ConvertWcsToScr(matrix.MultiplyPoint(s)).ToSKPoint();
                var cend = this.vportRt.ConvertWcsToScr(matrix.MultiplyPoint(e)).ToSKPoint();

                var closepen = this.GetDrawPen(element);
                if (grp.Curve2ds.Count > 1)
                {
                    if (closepen == Constants.defaultPen)
                    {
                        using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                        {

                            canvas.DrawLine(cstart, cend, elePen);
                        }
                    }
                    else
                    {
                        canvas.DrawLine(cstart, cend, closepen);
                    }
                }
            }

        }

        public override void CreateElement(LcElement element, Matrix3 matrix)
        {
            var grp = element as LcGroup;
            foreach (var ele in grp.Elements)
            {
                var eleAction = (ele.RtAction as ElementAction);
                eleAction.CreateElement(ele, matrix);
            }
        }
        public override void CreateElement(LcElement element, Vector2 basePoint, double scaleFactor)
        {
            var grp = element as LcGroup;
            foreach (var ele in grp.Elements)
            {
                var eleAction = (ele.RtAction as ElementAction);
                eleAction.CreateElement(ele, basePoint, scaleFactor);
            }

        }
        public override void CreateElement(LcElement element, Vector2 basePoint, Vector2 scaleVector)
        {
            var grp = element as LcGroup;
            foreach (var ele in grp.Elements)
            {
                var eleAction = (ele.RtAction as ElementAction);
                eleAction.CreateElement(ele, basePoint, scaleVector);
            }

        }
        private bool getCircleBy3P(Vector2 a, Vector2 b, Vector2 c, out Vector2 center, out double radius)
        {
            double A, B, C, D;
            double x1 = a.X, x2 = b.X, x3 = c.X;
            double y1 = a.Y, y2 = b.Y, y3 = c.Y;
            //已知三个点确定圆的半径和圆心 
            double x1x1 = x1 * x1;
            double y1y1 = y1 * y1;
            double x2x2 = x2 * x2;
            double y2y2 = y2 * y2;
            double x3x3 = x3 * x3;
            double y3y3 = y3 * y3;

            double x2y3 = x2 * y3;
            double x3y2 = x3 * y2;

            double x2_x3 = x2 - x3;
            double y2_y3 = y2 - y3;

            double x1x1py1y1 = x1x1 + y1y1;
            double x2x2py2y2 = x2x2 + y2y2;
            double x3x3py3y3 = x3x3 + y3y3;

            A = x1 * y2_y3 - y1 * x2_x3 + x2y3 - x3y2;
            if (A == 0)
            {
                center = null;
                radius = 0;
                return false;
            }
            B = x1x1py1y1 * (-y2_y3) + x2x2py2y2 * (y1 - y3) + x3x3py3y3 * (y2 - y1);
            C = x1x1py1y1 * x2_x3 + x2x2py2y2 * (x3 - x1) + x3x3py3y3 * (x1 - x2);
            D = x1x1py1y1 * (x3y2 - x2y3) + x2x2py2y2 * (x1 * y3 - x3 * y1) + x3x3py3y3 * (x2 * y1 - x1 * y2);

            var x = -B / (2 * A);
            var y = -C / (2 * A);
            radius = Math.Sqrt((B * B + C * C - 4 * A * D) / (4 * A * A));
            center = new Vector2(x, y);
            return true;
        }
        public Tuple<Vector2, Vector2, double> GetCircleBy2PD(Vector2 start, Vector2 End, double degrees)
        {
            double point1X = start.X;
            double point1Y = start.Y;
            double point2X = End.X;
            double point2Y = End.Y;
            double angleDegrees = degrees;

            // 计算中点坐标
            double midPointX = (point1X + point2X) / 2;
            double midPointY = (point1Y + point2Y) / 2;

            // 计算两个点之间的距离
            double distance = Math.Sqrt(Math.Pow(point2X - point1X, 2) + Math.Pow(point2Y - point1Y, 2));

            // 将角度转换为弧度
            double radians = angleDegrees * Math.PI / 180;

            double radius = distance / (2 * Math.Sin(radians / 2));
            //// 计算圆心的偏移量
            //double offsetX = distance * Math.Cos(radians);
            //double offsetY = distance * Math.Sin(radians);
            double centerX = midPointX + radius * Math.Cos(radians / 2);
            double centerY = midPointY + radius * Math.Sin(radians / 2);
            // 计算圆心的坐标
            //double centerX = midPointX + offsetX;
            //double centerY = midPointY + offsetY;
            //double radius = Math.Sqrt(Math.Pow(centerX - point1X, 2) + Math.Pow(centerY - point1Y, 2));


            double dx = point2X - point1X;
            double dy = point2Y - point1Y;

            ///# 将向量差单位化
            double unit_dx = dx / distance;
            double unit_dy = dy / distance;

            ///# 计算圆心坐标
            double h = midPointX + radius * unit_dx;
            double k = midPointY + radius * unit_dy;

            var b = start;
            var a = End;
            var r = radius;

            double c1 = (b.X * b.X - a.X * a.X + b.Y * b.Y - a.Y * a.Y) / (2 * (b.X - a.X));
            double c2 = (b.Y - a.Y) / (b.X - a.X);
            double A = (c2 * c2 + 1);
            double B = (2 * a.X * c2 - 2 * c1 * c2 - 2 * a.Y);
            double C = a.X * a.X - 2 * a.X * c1 + c1 * c1 + a.Y * a.Y - r * r;
            Vector2 center1 = new Vector2();
            Vector2 center2 = new Vector2();

            center1.Y = (-B - Math.Sqrt(B * B - 4 * A * C)) / (2 * A);

            center2.Y = (-B + Math.Sqrt(B * B - 4 * A * C)) / (2 * A);

            center1.X = c1 - c2 * center1.Y;
            center2.X = c1 - c2 * center2.Y;
            return new Tuple<Vector2, Vector2, double>(center1, center2, radius);
        }
        /// <summary>
        /// 切线加终止点画弧线  返回圆心和角度
        /// </summary>
        /// <param name="lineStart"></param>
        /// <param name="lineEnd"></param>
        /// <param name="point"></param>
        /// <returns>  圆心，半径，弧度</returns>
        public Tuple<Vector2, double, double> GetCircleBylinePoint(Vector2 lineStart, Vector2 lineEnd, Vector2 point)
        {
            //  return null;
            bool plugang = IsPlugAng(lineEnd, lineStart, lineEnd, point);
            bool pointIsTop = true;

            int tp = IsTopInLine(lineStart, lineEnd, point);
            if (tp == 0)
            {
                return null;//在同一条线上画直线
            }

            double Degrees = GetDegreesByTwoLine(lineStart, lineEnd, lineEnd, point);

            Degrees = 180 - (90 - Degrees) * 2;

            Tuple<Vector2, Vector2, double> cirTuple = GetCircleBy2PD(lineEnd, point, Degrees);
            int tc = IsTopInLine(lineEnd, point, cirTuple.Item1);
            Vector2 circenter;
            if (Degrees < 180)//圆心和线要在同一边 当弧度小于半圆，大于半圆时 ，向量反之  
            {
                if (tc == tp)
                    circenter = cirTuple.Item1;
                else circenter = cirTuple.Item2;
            }
            else
            {
                if (tc != tp)
                    circenter = cirTuple.Item1;
                else circenter = cirTuple.Item2;
            }
            /// 圆心，半径，弧度
            return new Tuple<Vector2, double, double>(circenter, cirTuple.Item3, Degrees);
        }

        /// <summary>
        /// 获取两条线的夹角  
        /// </summary>
        /// <param name="line1start"></param>
        /// <param name="line1End"></param>
        /// <param name="line2start"></param>
        /// <param name="line2End"></param>
        /// <returns></returns>
        public double GetDegreesByTwoLine(Vector2 line1start, Vector2 line1End, Vector2 line2start, Vector2 line2End)
        {
            double x1 = line1start.X;
            double y1 = line1start.Y;
            double x2 = line1End.X;
            double y2 = line1End.Y;
            double x3 = line2start.X;
            double y3 = line2start.Y;
            double x4 = line2End.X;
            double y4 = line2End.Y;

            // 计算线段的向量表示
            double v1x = x2 - x1;
            double v1y = y2 - y1;
            double v2x = x4 - x3;
            double v2y = y4 - y3;

            // 计算向量的内积
            double dotProduct = v1x * v2x + v1y * v2y;

            // 计算向量的长度
            double magnitudeV1 = Math.Sqrt(v1x * v1x + v1y * v1y);
            double magnitudeV2 = Math.Sqrt(v2x * v2x + v2y * v2y);

            // 计算夹角余弦值
            double cosine = dotProduct / (magnitudeV1 * magnitudeV2);

            // 将夹角余弦值转换为角度
            double angleRadians = Math.Acos(cosine);
            double angleDegrees = angleRadians * 180 / Math.PI;
            return angleDegrees;
        }
        public bool IsPlugAng(Vector2 line1start, Vector2 line1End, Vector2 line2start, Vector2 line2End)
        {
            double x1 = line1start.X;
            double y1 = line1start.Y;
            double x2 = line1End.X;
            double y2 = line1End.Y;
            double x3 = line2start.X;
            double y3 = line2start.Y;
            double x4 = line2End.X;
            double y4 = line2End.Y;
            if (x1 == x2)
            {
                if (x4 < x1)
                {
                    return true;

                }
                else
                {
                    return false;

                }
            }
            else
                if (y1 == y2)
            {
                if (y4 > y1)
                {
                    return true;

                }
                else
                {
                    return false;
                }
            }
            else
            {
                //             a = ( x1, y1) b = (x2, y2)
                //a×b = x1y2 - x2y1
                //若结果为正，则向量b在a的逆时针方向
                //否则，b在a的顺时针方向


                double xa = x2 - x1;
                double ya = y2 - y1;
                double xb = x4 - x3;
                double yb = y4 - y3;
                double angle = xa * yb - xb * ya;
                if (angle > 0)
                { return true; }
                else
                { return false; }
                //# 计算斜率
                //double m1 = (y2 - y1) / (x2 - x1);
                //double m2 = (y4 - y3) / (x4 - x3);
                //double angle = Math.Abs(Math.Tan(m2) - Math.Tan(m1));


                ////if (x2 > x1 && y2 > y1)
                ////{
                ////    if (m2 < m1)
                ////        return false;
                ////}
                ////else if (x2 < x1 && y2 > y1)
                ////{
                ////    if (m2 > m1)
                ////        return false;
                ////}
                ////else if (x2 < x1 && y2 < y1)
                ////{
                ////    if (m2 < m1)
                ////        return false;
                ////}
                ////else if (x2 > x1 && y2 < y1)
                ////{
                ////    if (m2 > m1)
                ////        return false;
                ////}
                //double angle1 = Math.Tan((m2 - m1) / (1 + m1 * m2));
                //if (angle1 > 0)
                //{ return false; }
                //else
                //{ return true; }



            }
        }
        public int IsTopInLine(Vector2 line1start, Vector2 line1End, Vector2 point)
        {
            Vector2 S;
            Vector2 E;
            //if (line1start.X < line1End.X)
            //{
            //    S = line1start;
            //    E = line1End;

            //}
            //else
            //   if (line1start.X == line1End.X)
            //{
            //    if (line1start.Y < line1End.Y)
            //    {
            //        S = line1start;
            //        E = line1End;

            //    }
            //    else
            //    {
            //        S = line1End;
            //        E = line1start;


            //    }
            //}
            //else
            //{
            S = line1End;
            E = line1start;

            // }
            double Tmp = (S.Y - E.Y) * point.X + (E.X - S.X) * point.Y + S.X * E.Y - E.X * S.Y;
            if (Tmp == 0)
            {
                return 0;
            }
            if (Tmp > 0)
            {
                return 1;
            }
            else
            { return -1; }
            //                Tmp > 0 在左侧

            //Tmp = 0 在线上

            //Tmp < 0 在右侧
        }
        public Vector2 GetVerticalpoint(Vector2 point, Vector2 center, Vector2 spoint, double ANG)
        {
            double x1 = point.X;
            double y1 = point.Y;
            double x2 = center.X;
            double y2 = center.Y;
            double x;
            double y;
            if (x1 == x2)
            {
                y = spoint.Y;
                x = x1;
            }
            else
            if (y1 == y2)
            {
                y = y1;
                x = spoint.X;
                //return (new(x1, y1 + 1));
            }
            else
            {
                double k1 = (y2 - y1) / (x2 - x1);


                double b1 = y1 - k1 * x1;
                double k = -1 / k1;
                double b = spoint.Y - k * spoint.X;
                x = (b1 - b) / (k - k1);
                y = k * x + b;

            }

            if (ANG < 180)
            {
                Matrix3 matrix31 = Matrix3.GetMove(new Vector2(x, y), point);
                return matrix31.MultiplyPoint(spoint);

            }
            else

            {
                Matrix3 matrix31 = Matrix3.GetMove(spoint, point);
                return matrix31.MultiplyPoint(new Vector2(x, y));
            }





        }
        public override void DrawTemp(SKCanvas canvas)
        {
            if (this.firstPoint == null)
            {
                return;
            }
            var mp = this.vportRt.PointerMovedPosition.ToVector2d();
            var wcs_mp = this.vportRt.ConvertScrToWcs(mp);
            var sk_p = this.vportRt.ConvertWcsToScr(wcs_mp).ToSKPoint();
            foreach (var ele in this.Segments)
            {

                SKPoint start = new SKPoint();
                SKPoint end = new SKPoint();
                if (ele.Type == Curve2dType.Line2d)
                {
                    start = this.vportRt.ConvertWcsToScr((ele as Line2d).Start).ToSKPoint();
                    end = this.vportRt.ConvertWcsToScr((ele as Line2d).End).ToSKPoint();
                    using (var elePen = new SKPaint { Color = this.vportRt.GetAuxColorValue(), IsStroke = true })
                    {
                        canvas.DrawLine(start, end, elePen);
                    }
                }
                else if (ele.Type == Curve2dType.Arc2d)
                {
                    start = this.vportRt.ConvertWcsToScr((ele as Arc2d).Startp).ToSKPoint();
                    end = this.vportRt.ConvertWcsToScr((ele as Arc2d).Endp).ToSKPoint();
                    using (var elePen = new SKPaint { Color = this.vportRt.GetAuxColorValue(), IsStroke = true })
                    {
                        Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
                        this.vportRt.DrawArc(ele as Arc2d, matrix, canvas, elePen);
                        //canvas.DrawLine(start, end, elePen);
                    }
                }
            }
            Vector2 startp = new Vector2(0, 0);//上一个元素的开始点

            if (Segments.Count == 0)
            {
                startp = new(this.firstPoint.X - 5, this.firstPoint.Y);
            }
            else if (Segments.LastOrDefault().Type == Curve2dType.Arc2d)
            {
                startp = GetVerticalpoint((Segments.LastOrDefault() as Arc2d).Endp, (Segments.LastOrDefault() as Arc2d).Center, (Segments.LastOrDefault() as Arc2d).Startp, Angle);
            }
            else
                startp = (Segments.LastOrDefault() as Line2d).Start;

            if (this.polyLineType == PlineSegmentType.Arc)
            {
                var cir = GetCircleBylinePoint(startp, this.firstPoint, wcs_mp);
                if (cir == null)
                {
                    using (var elePen = new SKPaint { Color = this.vportRt.GetAuxColorValue(), IsStroke = true })
                    {
                        canvas.DrawLine(this.vportRt.ConvertWcsToScr(this.firstPoint).ToSKPoint(), sk_p, elePen);
                    }
                    return;
                }
                Matrix3 matrix3 = Matrix3.GetTranslate(new Vector2(0, 0));
                using (var elePen = new SKPaint { Color = this.vportRt.GetAuxColorValue(), IsStroke = true })
                {
                    if (GeoUtils.IsTopInLine(startp, this.firstPoint, wcs_mp) > 0)
                    {
                        this.vportRt.DrawArc(Arc2d.CreatePCE(wcs_mp, cir.Item1, this.firstPoint), matrix3, canvas, elePen);


                    }
                    else
                        this.vportRt.DrawArc(Arc2d.CreatePCE(this.firstPoint, cir.Item1, wcs_mp), matrix3, canvas, elePen);
                }
                #region
                //var lcenter = this.vportRt.ConvertWcsToScr(cir.Item1).ToSKPoint();
                //double lEndAngle = cir.Item3;
                //double lradius = Math.Sqrt(Math.Pow(lcenter.X - sk_p.X, 2) + Math.Pow(lcenter.Y - sk_p.Y, 2));
                //float lx1 = (float)(lcenter.X - lradius);
                //float ly1 = (float)(lcenter.Y - lradius);
                //float lx2 = (float)(lcenter.X + lradius);
                //float ly2 = (float)(lcenter.Y + lradius);
                //SKRect lskrect = new SKRect(lx1, ly1, lx2, ly2);

                //bool ldr;
                //double DrawDegrees;//绘制的偏移角度
                //if (IsPlugAng(new(cir.Item1.X, cir.Item1.Y), new(this.firstPoint.X, this.firstPoint.Y), new(cir.Item1.X, cir.Item1.Y), new(wcs_mp.X, wcs_mp.Y)))

                //{
                //    if (lEndAngle > 180)
                //    {
                //        DrawDegrees = GetDegreesByTwoLine(new(cir.Item1.X, cir.Item1.Y), new(cir.Item1.X + lradius, cir.Item1.Y), new(cir.Item1.X, cir.Item1.Y), new(this.firstPoint.X, this.firstPoint.Y));
                //        ldr = IsPlugAng(new(cir.Item1.X, cir.Item1.Y), new(cir.Item1.X + lradius, cir.Item1.Y), new(cir.Item1.X, cir.Item1.Y), new(this.firstPoint.X, this.firstPoint.Y));
                //    }
                //    else
                //    {
                //        DrawDegrees = GetDegreesByTwoLine(new(cir.Item1.X, cir.Item1.Y), new(cir.Item1.X + lradius, cir.Item1.Y), new(cir.Item1.X, cir.Item1.Y), new(wcs_mp.X, wcs_mp.Y));
                //        ldr = IsPlugAng(new(cir.Item1.X, cir.Item1.Y), new(cir.Item1.X + lradius, cir.Item1.Y), new(cir.Item1.X, cir.Item1.Y), new(wcs_mp.X, wcs_mp.Y));
                //    }

                //}
                //else
                //{
                //    if (lEndAngle > 180)
                //    {
                //        DrawDegrees = GetDegreesByTwoLine(new(cir.Item1.X, cir.Item1.Y), new(cir.Item1.X + lradius, cir.Item1.Y), new(cir.Item1.X, cir.Item1.Y), new(wcs_mp.X, wcs_mp.Y));
                //        ldr = IsPlugAng(new(cir.Item1.X, cir.Item1.Y), new(cir.Item1.X + lradius, cir.Item1.Y), new(cir.Item1.X, cir.Item1.Y), new(wcs_mp.X, wcs_mp.Y));
                //    }
                //    else
                //    {
                //        DrawDegrees = GetDegreesByTwoLine(new(cir.Item1.X, cir.Item1.Y), new(cir.Item1.X + lradius, cir.Item1.Y), new(cir.Item1.X, cir.Item1.Y), new(this.firstPoint.X, this.firstPoint.Y));
                //        ldr = IsPlugAng(new(cir.Item1.X, cir.Item1.Y), new(cir.Item1.X + lradius, cir.Item1.Y), new(cir.Item1.X, cir.Item1.Y), new(this.firstPoint.X, this.firstPoint.Y));

                //    }
                //}

                //using (var elePen = new SKPaint { Color = SKColors.Gray, IsStroke = true })
                //{
                //    if (ldr)
                //    {
                //        canvas.DrawArc(lskrect, (float)(360.0 - DrawDegrees), (float)lEndAngle, false, elePen);
                //    }
                //    else canvas.DrawArc(lskrect, (float)DrawDegrees, (float)lEndAngle, false, elePen);

                //}
                //using (var elePen = new SKPaint { Color = SKColors.Yellow, IsStroke = true, PathEffect = SKPathEffect.CreateDash(new float[] { 10, 10, 30, 10 }, 0) })
                //{
                //    canvas.DrawLine(this.vportRt.ConvertWcsToScr(this.firstPoint).ToSKPoint(), sk_p, elePen);
                //}
                #endregion
            }
            else
            {
                using (var elePen = new SKPaint { Color = this.vportRt.GetAuxColorValue(), IsStroke = true })

                {
                    canvas.DrawLine(this.vportRt.ConvertWcsToScr(this.firstPoint).ToSKPoint(), sk_p, elePen);
                }
            }
        }
        public override void Draw(SKCanvas canvas, LcElement element, Matrix3 matrix)
        {
            var grp = element as LcPolyLine;
            foreach (var ele in grp.Curve2ds)
            {
                var pen = this.GetDrawPen(element);
                if (ele.Type == Curve2dType.Line2d)
                {
                    var mstart = matrix.MultiplyPoint((ele as Line2d).Start);
                    var mend = matrix.MultiplyPoint((ele as Line2d).End);
                    var start = this.vportRt.ConvertWcsToScr(mstart).ToSKPoint();
                    var end = this.vportRt.ConvertWcsToScr(mend).ToSKPoint();
                    if (pen == Constants.defaultPen)
                    {
                        using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                        {

                            canvas.DrawLine(start, end, elePen);
                        }
                    }
                    else
                    {
                        canvas.DrawLine(start, end, pen);
                    }
                }
                else if (ele.Type == Curve2dType.Arc2d)
                {
                    using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                    {
                        this.vportRt.DrawArc(ele as Arc2d, matrix, canvas, elePen);
                    }
                }
            }
            if (grp.IsClosed)
            {
                Vector2 s = new Vector2();
                Vector2 e = new Vector2();
                if (grp.Curve2ds.FirstOrDefault() is Line2d)
                {
                    s = (grp.Curve2ds.FirstOrDefault() as Line2d).Start;
                }
                else
                {
                    s = (grp.Curve2ds.FirstOrDefault() as Arc2d).Startp;
                }
                if (grp.Curve2ds.LastOrDefault() is Line2d)
                {
                    e = (grp.Curve2ds.LastOrDefault() as Line2d).End;
                }
                else
                {
                    e = (grp.Curve2ds.LastOrDefault() as Arc2d).Endp;
                }
                var cstart = this.vportRt.ConvertWcsToScr(s).ToSKPoint();
                var cend = this.vportRt.ConvertWcsToScr(e).ToSKPoint();

                var closepen = this.GetDrawPen(element);
                if (grp.Curve2ds.Count > 1)
                {
                    if (closepen == Constants.defaultPen)
                    {
                        using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                        {

                            canvas.DrawLine(cstart, cend, elePen);
                        }
                    }
                    else
                    {
                        canvas.DrawLine(cstart, cend, closepen);
                    }
                }
            }

        }
        public Vector2 Getmidpoint(Arc2d arc2D, Vector2 startPoint)
        {

            var sage = arc2D.StartAngle * 180 / Math.PI;
            var eage = arc2D.EndAngle * 180 / Math.PI;
            double moveAngle = eage - sage;
            if (moveAngle < 0)
            {
                moveAngle += 360;
            }
            double midAngle = (moveAngle / 2);  //需要旋转的角度
            var matrix3 = Matrix3.Rotate(midAngle, arc2D.Center); //围绕圆心旋转
            var mp = matrix3.MultiplyPoint(startPoint); //旋转矩阵是逆时针旋转
            return new Vector2(mp.X, mp.Y);
        }

        int num1;
        int num2;
        List<ControlGrip> grips = new List<ControlGrip>();
        List<string> strings = new List<string>();

        List<ControlGrip> lpoint1 = new List<ControlGrip>();
        public override ControlGrip[] GetControlGrips(LcElement element)
        {
            grips = new List<ControlGrip>();
            var polyline = element as LcPolyLine;

            string Name;
            for (int i = 0; i < polyline.Curve2ds.Count; i++)
            {
                var ele = polyline.Curve2ds[i];
                Vector2 start = LcPolyLine.GetStart(ele);
                Vector2 end = LcPolyLine.GetEnd(ele);
                Vector2 mid = new((start.X + end.X) / 2, (start.Y + end.Y) / 2); ;
                if (ele.Type == Curve2dType.Line2d)
                {
                    mid = mid;
                    Name = "Line";
                }
                else
                {

                    mid = (ele as Arc2d).Midp;
                    Name = "Arc";
                }

                var grippolylineStart = new ControlGrip
                {
                    Element = polyline,
                    Name = Name + i + "Start",
                    Position = start
                };
                grips.Add(grippolylineStart);

                var grippolylineMid = new ControlGrip
                {
                    Element = polyline,
                    Name = Name + i + "Mid",
                    Position = mid
                };
                grips.Add(grippolylineMid);

                var grippolylineEnd = new ControlGrip
                {
                    Element = polyline,
                    Name = Name + i + "End",
                    Position = end
                };
                grips.Add(grippolylineEnd);

            }
            return grips.ToArray();
        }
        private string _gripName;
        private Vector2 _position;
        private Vector2 _endDrag;
        private LcGroup _group;

        public override void SetDragGrip(LcElement element, string gripName, Vector2 position, bool isEnd)
        {
            _group = element as LcGroup;
            var polyline = element as LcPolyLine;
            strings = new List<string>();

            List<ControlGrip> lpoint = new List<ControlGrip>();
            lpoint1 = new List<ControlGrip>();
            if (!isEnd)
            {
                _gripName = gripName;//要拖拽的点
                _position = position;//拖拽的位置，时刻变化
            }
            else
            {
                int num;
                int num1;
                Vector2 mid;
                Vector2 mid1;
                Vector2 vector;
                Vector2 temporaryPoint1;
                //捕捉点
                Vector2 dragposition = position;
                if (this.vportRt.SnapRt?.Current != null)
                {
                    dragposition = this.vportRt.SnapRt.Current.SnapPoint;
                }
                //利用名字寻找原始点
                Vector2 originalPoint = new Vector2();
                for (int i = 0; i < grips.Count; i++)
                {
                    if (gripName == grips[i].Name)
                    {
                        originalPoint = grips[i].Position;
                        break;
                    }
                }
                //利用原始点遍历所有位置相同的点
                for (int j = 0; j < grips.Count; j++)
                {
                    if (originalPoint == grips[j].Position)
                    {
                        lpoint.Add(grips[j]);
                    }
                }
                for (int k = 0; k < lpoint.Count; k++)
                {
                    num = int.Parse(System.Text.RegularExpressions.Regex.Replace(lpoint[k].Name, @"[^0-9]+", ""));
                    if (lpoint[k].Name.StartsWith("Line"))
                    {
                        if (lpoint[k].Name.EndsWith("Start"))
                        {
                            (polyline.Curve2ds[num] as Line2d).Start = dragposition;
                        }
                        else if (lpoint[k].Name.EndsWith("End"))
                        {
                            (polyline.Curve2ds[num] as Line2d).End = dragposition;
                        }
                        else
                        {
                            mid = lpoint[k].Position;
                            vector = new(dragposition.X - mid.X, dragposition.Y - mid.Y);

                            if (num == 0)
                            {
                                if (polyline.Curve2ds[num + 1].Type == Curve2dType.Line2d)
                                {
                                    (polyline.Curve2ds[num + 1] as Line2d).Start += vector;
                                }
                                else
                                {
                                    bool df = false;

                                    mid1 = (polyline.Curve2ds[num + 1] as Arc2d).Midp;
                                    //利用三点创建新的弧线
                                    Arc2d arc1 = new Arc2d();
                                    if (LcPolyLine.GetStart(polyline.Curve2ds[num + 1]) == LcPolyLine.GetEnd(polyline.Curve2ds[num]))
                                    {
                                        temporaryPoint1 = LcPolyLine.GetStart(polyline.Curve2ds[num + 1]) + vector;
                                        //利用三点创建新的弧线
                                        arc1 = Arc2d.CreateARC(temporaryPoint1, mid1, LcPolyLine.GetEnd(polyline.Curve2ds[num + 1]));
                                        polyline.Curve2ds[num + 1] = arc1;
                                    }
                                    else
                                    {
                                        temporaryPoint1 = LcPolyLine.GetEnd(polyline.Curve2ds[num + 1]) + vector;
                                        arc1 = Arc2d.CreateARC(LcPolyLine.GetStart(polyline.Curve2ds[num + 1]), mid1, temporaryPoint1);
                                        polyline.Curve2ds[num + 1] = arc1;
                                    }
                                }

                            }
                            else if (num == polyline.Curve2ds.Count - 1)
                            {
                                if (polyline.Curve2ds[num - 1].Type == Curve2dType.Line2d)
                                {
                                    (polyline.Curve2ds[num - 1] as Line2d).End += vector;
                                }
                                else
                                {
                                    bool df = false;

                                    mid1 = (polyline.Curve2ds[num - 1] as Arc2d).Getmidpoint();
                                    Arc2d arc1 = new Arc2d();
                                    if (LcPolyLine.GetEnd(polyline.Curve2ds[num - 1]) == LcPolyLine.GetStart(polyline.Curve2ds[num]))
                                    {
                                        temporaryPoint1 = LcPolyLine.GetEnd(polyline.Curve2ds[num - 1]) + vector;
                                        arc1 = Arc2d.CreateARC(LcPolyLine.GetStart(polyline.Curve2ds[num - 1]), mid1, temporaryPoint1);
                                        polyline.Curve2ds[num - 1] = arc1;
                                    }
                                    else
                                    {
                                        temporaryPoint1 = LcPolyLine.GetStart(polyline.Curve2ds[num - 1]) + vector;
                                        arc1 = Arc2d.CreateARC(temporaryPoint1, mid1, LcPolyLine.GetEnd(polyline.Curve2ds[num - 1]));
                                        polyline.Curve2ds[num - 1] = arc1;
                                    }

                                }

                            }
                            else
                            {
                                if (polyline.Curve2ds[num - 1].Type == Curve2dType.Line2d)
                                {
                                    (polyline.Curve2ds[num - 1] as Line2d).End += vector;
                                }

                                else
                                {
                                    bool df = false;

                                    mid1 = (polyline.Curve2ds[num - 1] as Arc2d).Getmidpoint();

                                    Arc2d arc1 = new Arc2d();
                                    if (LcPolyLine.GetEnd(polyline.Curve2ds[num - 1]) == LcPolyLine.GetStart(polyline.Curve2ds[num]))
                                    {
                                        temporaryPoint1 = LcPolyLine.GetEnd(polyline.Curve2ds[num - 1]) + vector;
                                        arc1 = Arc2d.CreateARC(LcPolyLine.GetStart(polyline.Curve2ds[num - 1]), mid1, temporaryPoint1);
                                        polyline.Curve2ds[num - 1] = arc1;
                                    }
                                    else
                                    {
                                        temporaryPoint1 = LcPolyLine.GetStart(polyline.Curve2ds[num - 1]) + vector;
                                        arc1 = Arc2d.CreateARC(temporaryPoint1, mid1, LcPolyLine.GetEnd(polyline.Curve2ds[num - 1]));
                                        polyline.Curve2ds[num - 1] = arc1;
                                    }


                                }
                                if (polyline.Curve2ds[num + 1].Type == Curve2dType.Line2d)
                                {
                                    (polyline.Curve2ds[num + 1] as Line2d).Start += vector;
                                }
                                else
                                {
                                    bool df = false;
                                    Arc2d arc2D = new Arc2d();

                                    mid1 = (polyline.Curve2ds[num + 1] as Arc2d).Getmidpoint();

                                    //利用三点创建新的弧线
                                    Arc2d arc1 = new Arc2d();
                                    if (LcPolyLine.GetStart(polyline.Curve2ds[num + 1]) == LcPolyLine.GetEnd(polyline.Curve2ds[num]))
                                    {
                                        temporaryPoint1 = LcPolyLine.GetStart(polyline.Curve2ds[num + 1]) + vector;
                                        arc1 = Arc2d.CreateARC(temporaryPoint1, mid1, LcPolyLine.GetEnd(polyline.Curve2ds[num + 1]));
                                        polyline.Curve2ds[num + 1] = arc1;
                                    }
                                    else
                                    {
                                        temporaryPoint1 = LcPolyLine.GetEnd(polyline.Curve2ds[num + 1]) + vector;
                                        arc1 = Arc2d.CreateARC(LcPolyLine.GetStart(polyline.Curve2ds[num + 1]), mid1, temporaryPoint1);
                                        polyline.Curve2ds[num + 1] = arc1;
                                    }


                                }
                            }
                            (polyline.Curve2ds[num] as Line2d).Start += vector;
                            (polyline.Curve2ds[num] as Line2d).End += vector;
                        }
                    }
                    else
                    {
                        bool df = false;
                        if (lpoint[k].Name.EndsWith("Start"))
                        {
                            //求原弧线的线中点
                            mid1 = (polyline.Curve2ds[num] as Arc2d).Getmidpoint();
                            //利用三点创建新的弧线
                            Arc2d arc1 = Arc2d.CreateARC(dragposition, mid1, LcPolyLine.GetEnd(polyline.Curve2ds[num]));
                            polyline.Curve2ds[num] = arc1;

                        }
                        else if (lpoint[k].Name.EndsWith("End"))
                        {
                            mid1 = (polyline.Curve2ds[num] as Arc2d).Getmidpoint();
                            //利用三点创建新的弧线
                            Arc2d arc1 = Arc2d.CreateARC(LcPolyLine.GetStart(polyline.Curve2ds[num]), mid1, dragposition);
                            polyline.Curve2ds[num] = arc1;

                        }
                        else
                        {
                            Arc2d arc = Arc2d.CreateARC(LcPolyLine.GetStart(polyline.Curve2ds[num]), dragposition, LcPolyLine.GetEnd(polyline.Curve2ds[num]));
                            polyline.Curve2ds[num] = arc;

                        }
                    }
                }
            }
        }
        private Vector2 center;
        public Arc2d GetArc2DBy3P(Vector2 sp, Vector2 mp, Vector2 ep, out bool df)    //第一个点  第二个点  第三个点
        {
            df = false;
            Arc2d arc2D = new Arc2d();
            arc2D.Center = GeoUtils.GetCenter(sp, mp, ep);
            this.center = arc2D.Center;
            arc2D.Radius = Vector2.Distance(sp, arc2D.Center);
            double Degrees, smidAngle, emidAngle;
            arc2D.StartAngle = GetDegreesByTwoLine(new(arc2D.Center.X, arc2D.Center.Y), new(arc2D.Center.X + arc2D.Radius, arc2D.Center.Y), new(arc2D.Center.X, arc2D.Center.Y), new(sp.X, sp.Y)); //计算圆弧的起始角度
            arc2D.EndAngle = GetDegreesByTwoLine(new(arc2D.Center.X, arc2D.Center.Y), new(arc2D.Center.X + arc2D.Radius, arc2D.Center.Y), new(arc2D.Center.X, arc2D.Center.Y), new(ep.X, ep.Y));  //计算圆弧的结束角度
            smidAngle = GetDegreesByTwoLine(new(arc2D.Center.X, arc2D.Center.Y), new(sp.X, sp.Y), new(arc2D.Center.X, arc2D.Center.Y), new(mp.X, mp.Y));  //起始点到中点之间的角度
            emidAngle = GetDegreesByTwoLine(new(arc2D.Center.X, arc2D.Center.Y), new(ep.X, ep.Y), new(arc2D.Center.X, arc2D.Center.Y), new(mp.X, mp.Y));
            if (IsTopInLine(arc2D.Center, sp, new(arc2D.Center.X + arc2D.Radius, arc2D.Center.Y)) < 0)
            {
                arc2D.StartAngle = 360 - arc2D.StartAngle;
            }
            if (IsTopInLine(arc2D.Center, ep, new(arc2D.Center.X + arc2D.Radius, arc2D.Center.Y)) < 0)
            {
                arc2D.EndAngle = 360 - arc2D.EndAngle;
            }
            double moveAngle = smidAngle + emidAngle;
            double xAngle = arc2D.EndAngle - arc2D.StartAngle;
            if (xAngle < 0)
            {
                xAngle += 360;
            }
            if (LcArc.IsAngleTrue(xAngle, moveAngle) == true)
            //if (xAngle -0.001< moveAngle&& moveAngle< xAngle+0.001) //防止弧度和角度转化发生错误而导致角度计算不对
            {
                arc2D.StartAngle = arc2D.StartAngle / 180 * Math.PI;
                arc2D.EndAngle = arc2D.EndAngle / 180 * Math.PI;
            }
            else
            {
                //LcArc.IsAngleTrue(xAngle, moveAngle);
                Degrees = arc2D.StartAngle;
                df = true;
                //this.startPoint = ep;
                //this.endPoint = sp;
                arc2D.StartAngle = arc2D.EndAngle / 180 * Math.PI;
                arc2D.EndAngle = Degrees / 180 * Math.PI;
            }
            return arc2D;
        }

        public override void DrawDragGrip(SKCanvas canvas)
        {
            Vector2 dragposition = _position;
            if (this.vportRt.SnapRt?.Current != null)
            {
                dragposition = this.vportRt.SnapRt.Current.SnapPoint;
            }
            if (_gripName == null) return;
            Vector2 originalPoint = new Vector2();
            Vector2 temporaryPoint = new Vector2();
            Vector2 temporaryPt = new Vector2();
            List<ControlGrip> lpoint = new List<ControlGrip>();
            for (int i = 0; i < grips.Count; i++)
            {
                if (_gripName == grips[i].Name)
                {
                    originalPoint = grips[i].Position;
                    break;
                }
            }

            //利用原始点遍历所有位置相同的点
            for (int j = 0; j < grips.Count; j++)
            {
                if (originalPoint == grips[j].Position)
                {
                    lpoint.Add(grips[j]);
                }
            }
            var drawPolyline = grips[0].Element as LcPolyLine;
            List<Line2d> drawlines = new List<Line2d>();
            List<Arc2d> drawarcs = new List<Arc2d>();
            Vector2 mid, vector;
            Vector2 mid1;
            for (int k = 0; k < lpoint.Count; k++)
            {
                bool df = false;
                int num1 = int.Parse(System.Text.RegularExpressions.Regex.Replace(lpoint[k].Name, @"[^0-9]+", ""));
                if (lpoint[k].Name.StartsWith("Line"))
                {
                    if (lpoint[k].Name.EndsWith("Start"))
                    {

                        Line2d line = new Line2d();
                        line.Start = dragposition;
                        line.End = LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1]);
                        drawlines.Add(line);
                    }
                    else if (lpoint[k].Name.EndsWith("End"))
                    {
                        Line2d line = new Line2d();
                        line.Start = LcPolyLine.GetStart(drawPolyline.Curve2ds[num1]);
                        line.End = dragposition;
                        drawlines.Add(line);
                    }
                    else
                    {
                        Line2d line = new Line2d();
                        mid = lpoint[k].Position;
                        vector = new(dragposition.X - mid.X, dragposition.Y - mid.Y);

                        drawlines.Add(line);
                        if (num1 == 0)
                        {
                            if (drawPolyline.Curve2ds[num1 + 1].Type == Curve2dType.Line2d)
                            {
                                Line2d line1 = new Line2d();
                                line1.Start = LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 + 1]) + vector;
                                line1.End = LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 + 1]);
                                drawlines.Add(line1);
                            }
                            else
                            {

                                mid1 = (drawPolyline.Curve2ds[num1 + 1] as Arc2d).Getmidpoint();
                                Arc2d arc1 = new Arc2d();
                                if (LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 + 1]) == LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1]))
                                {
                                    temporaryPoint = LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 + 1]) + vector;
                                    arc1 = Arc2d.CreateARC(temporaryPoint, mid1, LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 + 1]));
                                }
                                else
                                {
                                    temporaryPoint = LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 + 1]) + vector;
                                    arc1 = Arc2d.CreateARC(LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 + 1]), mid1, temporaryPoint);
                                }
                                drawarcs.Add(arc1);
                            }
                        }
                        else if (num1 == drawPolyline.Curve2ds.Count - 1)
                        {
                            if (drawPolyline.Curve2ds[num1 - 1].Type == Curve2dType.Line2d)
                            {
                                Line2d line1 = new Line2d();
                                line1.End = LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 - 1]) + vector;
                                line1.Start = LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 - 1]);
                                drawlines.Add(line1);
                            }
                            else
                            {

                                mid1 = (drawPolyline.Curve2ds[num1 - 1] as Arc2d).Getmidpoint();
                                Arc2d arc1 = new Arc2d();
                                if (LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 - 1]) == LcPolyLine.GetStart(drawPolyline.Curve2ds[num1]))
                                {
                                    temporaryPoint = LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 - 1]) + vector;
                                    arc1 = Arc2d.CreateARC(LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 - 1]), mid1, temporaryPoint);
                                }
                                else
                                {
                                    temporaryPoint = LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 - 1]) + vector;
                                    arc1 = Arc2d.CreateARC(temporaryPoint, mid1, LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 - 1]));
                                }
                                drawarcs.Add(arc1);
                            }
                        }
                        else
                        {
                            if (drawPolyline.Curve2ds[num1 + 1].Type == Curve2dType.Line2d)
                            {
                                Line2d line1 = new Line2d();
                                line1.Start = LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 + 1]) + vector;
                                line1.End = LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 + 1]);
                                drawlines.Add(line1);
                            }
                            else
                            {

                                mid1 = (drawPolyline.Curve2ds[num1 + 1] as Arc2d).Getmidpoint();

                                Arc2d arc1 = new Arc2d();
                                if (LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 + 1]) == LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1]))
                                {
                                    temporaryPoint = LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 + 1]) + vector;
                                    arc1 = Arc2d.CreateARC(temporaryPoint, mid1, LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 + 1]));
                                }
                                else
                                {
                                    temporaryPoint = LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 + 1]) + vector;
                                    arc1 = Arc2d.CreateARC(LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 + 1]), mid1, temporaryPoint);
                                }
                                drawarcs.Add(arc1);
                            }
                            if (drawPolyline.Curve2ds[num1 - 1].Type == Curve2dType.Line2d)
                            {
                                Line2d line2 = new Line2d();
                                line2.End = LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 - 1]) + vector;
                                line2.Start = LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 - 1]);
                                drawlines.Add(line2);
                            }
                            else
                            {
                                mid1 = (drawPolyline.Curve2ds[num1 - 1] as Arc2d).Getmidpoint();
                                Arc2d arc1 = new Arc2d();
                                if (LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 - 1]) == LcPolyLine.GetStart(drawPolyline.Curve2ds[num1]))
                                {
                                    temporaryPoint = LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 - 1]);

                                    arc1 = Arc2d.CreateARC(temporaryPoint, mid1, LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 - 1]) + vector);
                                }
                                else
                                {
                                    temporaryPoint = LcPolyLine.GetStart(drawPolyline.Curve2ds[num1 - 1]) + vector;
                                    arc1 = Arc2d.CreateARC(temporaryPoint, mid1, LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1 - 1]));
                                }
                                drawarcs.Add(arc1);
                            }
                        }
                        line.Start = LcPolyLine.GetStart(drawPolyline.Curve2ds[num1]) + vector;
                        line.End = LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1]) + vector;
                    }
                }
                else
                {
                    if (lpoint[k].Name.EndsWith("Start"))
                    {
                        //求原弧线的线中点

                        mid1 = (drawPolyline.Curve2ds[num1] as Arc2d).Getmidpoint();

                        //利用三点创建新的弧线
                        Arc2d arc1 = GetArc2DBy3P(dragposition, mid1, LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1]), out df);
                        drawarcs.Add(arc1);
                    }
                    else if (lpoint[k].Name.EndsWith("End"))
                    {
                        //求原弧线的线中点
                        mid1 = (drawPolyline.Curve2ds[num1] as Arc2d).Getmidpoint();
                        Arc2d arc1 = Arc2d.CreateARC(LcPolyLine.GetStart(drawPolyline.Curve2ds[num1]), mid1, dragposition);
                        drawarcs.Add(arc1);
                    }
                    else
                    {
                        Arc2d arc1 = Arc2d.CreateARC(LcPolyLine.GetStart(drawPolyline.Curve2ds[num1]), dragposition, LcPolyLine.GetEnd(drawPolyline.Curve2ds[num1]));
                        drawarcs.Add(arc1);
                    }
                }
            }
            foreach (var ele in drawlines)
            {
                canvas.DrawLine(this.vportRt.ConvertWcsToScr(ele.Start).ToSKPoint(), this.vportRt.ConvertWcsToScr(ele.End).ToSKPoint(), Constants.draggingPen);
            }
            foreach (var ele in drawarcs)
            {
                Matrix3 matrix = Matrix3.GetTranslate(new Vector2(0, 0));
                Arc2d arc = new Arc2d();
                arc.IsClockwise = false;
                arc.StartAngle = ele.StartAngle;
                arc.EndAngle = ele.EndAngle;
                arc.Center = ele.Center;
                arc.Radius = ele.Radius;
                this.vportRt.DrawArc(arc, matrix, canvas, Constants.auxElementPen);
            }
            canvas.DrawLine(this.vportRt.ConvertWcsToScr(dragposition).ToSKPoint(), this.vportRt.ConvertWcsToScr(originalPoint).ToSKPoint(), Constants.draggingPen);

            //    var offset = _position - _group.BoundingBox.Center;
            //foreach (var ele in _group.Elements)
            //{
            //    (ele.RtAction as ElementAction).Draw(canvas, ele, offset);
            //}
        }
        public override List<PropertyObserver> GetPropertyObservers()
        {
            return new List<PropertyObserver>()
            {
                new PropertyObserver()
                {
                    Name = "CurrentIndex",
                    DisplayName = "当前顶点",
                    CategoryName = "Geometry",
                    CategoryDisplayName = "几何图形",
                    PropType = PropertyType.Array,
                    Source = (ele) =>
                    {
                        var pline = (ele as LcPolyLine);
                        List<string> count = new List<string>();
                        for (int i = 0; i < pline.Curve2ds.Count + 1; i++)
                        {
                            count.Add(i.ToString());
                        }

                        return count.ToArray();
                    },
                    Getter = (ele) => (ele as LcPolyLine).CurrentIndex,
                    Setter = (ele, value) =>
                    {
                        (ele as LcPolyLine).CurrentIndex = Convert.ToInt32(value);

                    }
                },
                new PropertyObserver()
                {
                    Name = "PositionX",
                    DisplayName = "顶点 X 坐标",
                    CategoryName = "Geometry",
                    CategoryDisplayName = "几何图形",
                    Getter = (ele) =>
                    {
                        var pline = (ele as LcPolyLine);
                        var point = pline.GetCurrentPoint();
                        return point.X;
                    },
                    Setter = (ele, value) =>
                    {
                        var pline = (ele as LcPolyLine);
                        Curve2d curCurve = null;
                        var point = pline.GetCurrentPoint();
                        var x = Convert.ToDouble(value);
                        var sp = new Vector2(x, point.Y);
                        pline.SetCurrentCurvePos(sp);
                    }
                }
            };
        }
    }
}

